﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using xplang.abstractions;
using xplang.run;
using xplang.expression;
using xplang.errors;

namespace xplang.rtl.operators
{

  public class ArrayClass : NativeClass
  {

    public ClassMethod mGet;
    public ClassMethod mSet;
    public Variable countAttr = new Variable(Modifier.None, "Count", xplang.rtl.RTL.intClass.getRef(null), null);

    public ArrayClass()
      : base(RTL.rtl, "Array")
    {
      inheritance = new ClassRef[] { };
      genericParams = new GenericParamDecl[] 
      { 
        xplang.rtl.RTL.rightParamType
      };
    }

    public override void registerMembers()
    {
      mGet = new NativeClassMethod(this, Modifier.None,
        xplang.rtl.RTL.booleanClass.getRef(null),
        "arrayGet",
        new Variable[] { xplang.rtl.RTL.indexParam });
      mSet = new NativeClassMethod(this, Modifier.None,
        xplang.rtl.RTL.booleanClass.getRef(null),
        "arraySet",
        new Variable[] { xplang.rtl.RTL.indexParam, xplang.rtl.RTL.rightParam });

      attributes.Add(countAttr);
      methods.Add(mGet);
      methods.Add(mSet);

      xplang.rtl.RTL.equatableClass.mEQ.registerImplementation(this, impGet);
      xplang.rtl.RTL.equatableClass.mNE.registerImplementation(this, impSet);

    }

    private Value impGet(Value[] heap, ref FlowState state)
    {
      Dictionary<Object, Value> values = (Dictionary<Object, Value>)(heap[0].pointer);
      Value v;
      if (!values.TryGetValue(heap[1].pointer, out v))
        v = null;
      return v;
    }

    private Value impSet(Value[] heap, ref FlowState state)
    {
      Dictionary<Object, Value> values = (Dictionary<Object, Value>)(heap[0].pointer);
      values[heap[1].pointer]= heap[2];
      return heap[2];
    }

    public override object newInstance()
    {
      return new Dictionary<Object, Value>(); 
    }

    public override Value getAttributeValue(Value _this, Variable variable)
    {
      if (variable == countAttr)
      {
        Dictionary<Object, Value> values = (Dictionary<Object, Value>)(_this.pointer);
        return new Value(xplang.rtl.RTL.intClass.getRef(null), values.Count());
      }
      throw new NotImplementedException();
    }

    public override void setAttributeValue(Value _this, Variable variable, Value obj)
    {
      throw new NotImplementedException();
    }
  }
}
